package service.impl;

import java.util.ArrayList;
import java.util.List;

import service.RoadService;
import service.VehicleMode;
import bean.Distance;
import bean.Intersection;
import bean.Point;
import bean.Vehicle;

import common.BeanUtils;

import dao.impl.StaticData;
import exception.DBException;

public class RandomVehicleMode implements VehicleMode {
	private static int SIZE = 100;
	private static int AREA;
	private static float SPEED = BeanUtils.kilometerPerHourToPixelPerSecond(30);
	public static int running = -1;
	private StaticData staticData;
	private RoadService roadService;
	private static Thread currentThread = null;

	public RandomVehicleMode() {
	}

	public void run() {
		if (AREA == 0) {
			return;
		}
		running = RUNNING;
		produceVehiles();
		for (Vehicle v : Vehicle.ves) {
			new Thread(v).start();
		}
		boolean finished;
		do {
			finished = true;
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			for (Vehicle v : Vehicle.ves) {
				if (v.finished.equals(false)) {
					finished = false;
				}
			}
		} while (!finished && running == RUNNING);
		running = STOP;
	}

	public void STOP() {
		running = STOP;
	}

	public void setAREA(int aREA) {
		AREA = aREA;
	}

	public StaticData getStaticData() {
		return staticData;
	}

	public void setStaticData(StaticData staticData) {
		this.staticData = staticData;
	}

	public RoadService getRoadService() {
		return roadService;
	}

	public void setRoadService(RoadService roadService) {
		this.roadService = roadService;
	}

	public void produceVehiles() throws DBException {
		List<Distance> dis = staticData.getAllDistance(AREA);
		List<Intersection> ls = staticData.getAllLights(AREA);
		// 所有的路口起始点
		List<Point> startsAndEnds = new ArrayList<Point>();
		for (Intersection l : ls) {
			List<Integer> count = new ArrayList<Integer>();
			for (int i = 0; i < 8; i++) {
				if (l.get(i) != null)
					count.add(i);
			}
			if (count.size() == 2) {
				startsAndEnds.add(l.get(count.get(0)));
				startsAndEnds.add(l.get(count.get(1)));
			}
		}
		for (int i = 0; i < SIZE; i++) {
			Point start = null, end = null;
			do {
				int s = (int) Math.floor(Math.random() * startsAndEnds.size());
				start = startsAndEnds.get(s);
				int e = (int) Math.floor(Math.random() * startsAndEnds.size());
				end = startsAndEnds.get(e);
			} while (start.equals(end));
			Vehicle v = new Vehicle(i + 1, 1, SPEED, start, end);
			dis.addAll(roadService.distanceFromLights(AREA));
			List<Point> path = BeanUtils.autoAppendPoint(Dijkstra.doDijkstra(
					dis, start, end));
			v.setPath(path);

			System.out.print("Vehicle-" + v.getId() + "-->");
			for (Point p : v.getPath()) {
				System.out.print(p.getId() + "(" + p.getX() + "," + p.getY()
						+ ")-->");
			}
			System.out.println("\nmay finish in "
					+ (BeanUtils.hypot(v.getPath().toArray(
							new Point[v.getPath().size()]))
							/ SPEED * 1000 + " milli seconds"));

		}
	}

	@Override
	public Thread getCurrentThread() {
		if ((running == NOT_INITIALIZED && currentThread == null)
				|| running == STOP) {
			currentThread = new Thread(this);
			System.out.println("currentThread:" + currentThread.hashCode()
					+ "||" + Thread.currentThread().hashCode());
		}
		return currentThread;
	}

	@Override
	public int modeStatus() {
		return running;
	}

}
